package org.example.n21both;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;


/**
 * @author zhaokuii11@163.com
 * @create 2021-12-06 9:54
 * @Description
 */
public class Test1 {
    private SessionFactory sessionFactory;//会话工厂
    private Session session;//会话
    private Transaction transaction;//事务

    @Before //juint测试方法 之前执行
    public void init() {
        System.out.println("init");
        //1. 根据 Configuration创建 会话工厂
        sessionFactory = new Configuration().configure().buildSessionFactory();
        //2. 创建 会话
        session = sessionFactory.openSession();
        //3. 创建事务
        transaction = session.beginTransaction();
    }

    @Test
    public void testCascade() {
        //  cascade="delete-orphan" 只删除 n set集合
        Customer customer = session.get(Customer.class, 3);
        customer.getOrders().clear();
    }

    @Test
    public void testDelete() {
        //不设定级联关系的情况下，且1这一端的对象有 n的对象在引用，不能删除1这一端的对象
        //设置   cascade="delete" 级联删除
        Customer customer = session.get(Customer.class, 2);
        session.delete(customer);
    }

    @Test
    public void testUpdate() {
        Customer customer = session.get(Customer.class, 1);
        customer.getOrders().iterator().next().setOrderName("update-1");
    }

    @Test
    public void testOne2ManyGet() {
        //1. 对 n 的一端的集合使用延迟加载
        Customer customer = session.get(Customer.class, 4);
        System.out.println(customer.getCustomerName());
        //2. 返回的多的一端的集合 hibernate 内置的集合类型
        //该类具有延迟加载和存放代理对象的功能。
        System.out.println(customer.getOrders().getClass());
        //session.close();
        System.out.println(customer.getOrders());
        //3. 如果session 关闭，可能会抛出 org.hibernate.LazyInitializationException
        //4. 在需要使用集合中元素的时候进行初始化。
    }

    @Test
    public void testMany20neSave() {
        Customer customer = new Customer(1, "FF");
        //设定关联关系
        Order order1 = new Order(null, "order-11", customer);
        Order order2 = new Order(null, "order-12", customer);
        customer.getOrders().add(order1);
        customer.getOrders().add(order2);
        //1. 先执行 save操作，先插入 customer，再插入 order；三条 insert 两条update
//        session.save(customer);
//        session.save(order1);
//        session.save(order2);

        //2. 如果没有给 Customer id进行赋值报错误 org.hibernate.exception.ConstraintViolationException
        //如果给 Customer id进行赋值【赋值后不会在数据库插入id(主键)】，先插入 order，再插入 customer；三条 insert 两条 update
        session.save(order1);
        session.save(order2);
        session.save(customer);
        //3. 如果在1的一端的集合节点 inverse="true"，来使1的一端放弃维护关联关系
        //如果没有给 Customer设置id报错 org.hibernate.exception.ConstraintViolationException
        //如果设置了 customer id，执行三条 insert，下插入 order，再插入 customer【不插入 id】，插入的order会根据 customer的id插入，
        //==》如果customer的id不存在报错，存在，order插入的是 customer的id。
        //建议设置 set的 inverse="true"，建议下插入1的一端，后插入多的一端。好处是不会插入 update
    }


    @After//juint测试方法 之后执行
    public void destroy() {
        //先开后关
        System.out.println("destroy");
        transaction.commit();
        session.close();
        sessionFactory.close();
    }
}
